home *** CD-ROM | disk | FTP | other *** search
/ Font Garden / Font Garden (Walnut Creek) (October 1995) (1995).iso / pc / fontutil / uncompre / readobe1 / readobe.c next >
Encoding:
C/C++ Source or Header  |  1991-10-04  |  10.3 KB  |  421 lines

  1. /* reAdobe.c 1.1
  2.  *
  3.  * Copyright 1990, 1991 by Rob Elliott. All rights reserved.
  4.  * Source code and executables may be freely distributed with the
  5.  * copyright notice intact.
  6.  *
  7.  * Converts a type 1 font in text format (as used on NeXT computers,
  8.  * for example ) into a Macintosh downloadable Type 1 font using
  9.  * a resource fork format.  By default, ".res" is appended to the
  10.  * original filename.
  11.  *
  12.  * Developed with THINK C version 4.0.  Contact me if you want to
  13.  * help spruce this up.  I envision a general purpose font converter,
  14.  * also converting from binary -> text (currently done by the unAdobe
  15.  * utility written elsewhere), as well as converting Type 1 -> Type 3
  16.  * and supporting the MS-DOS file format.
  17.  *
  18.  * References:
  19.  * _Supporting Downloadable Postscript(R in a Circle) Fonts_
  20.  * Technical Note #5040 by Adobe Systems Incorporated.  This
  21.  * is available from their mail server on Internet, or through
  22.  * the Developer support group.
  23.  *
  24.  * _Adobe Type 1 Font Format_, the "black book" by Adobe. 
  25.  *
  26.  * Rob Elliott
  27.  * Compuserve: 70675,1204
  28.  * Internet: relliott@b11.ingr.com
  29.  * 1030 Bayshore Drive #711, Huntsville, AL 35824
  30.  *
  31.  */
  32.  
  33. #include <stdio.h>
  34. #define nil NULL
  35. /*#define DEBUG*/
  36.  
  37. #define ASCIIDATA '\001'
  38. #define HEXDATA '\002'
  39. #define ENDOFFILE '\003'
  40. #define ENDOFFONT '\005'
  41.  
  42. /* Prototypes */
  43. int htoi(char *s);
  44. int getinfile(Str255 filename);
  45. int getoutfile(Str255 filename);
  46. OSErr input(char *c);
  47. int output(char c,char resnum);
  48. int writeres(char resnum);
  49. void initbuf(void);
  50. void cvt(void);
  51. void resumeProc(void);
  52. void main(int argc, char *argv[]);
  53.  
  54. /* Globals */
  55. #define INBUFMAX 1024        /* ideal maximum size of input buffer */
  56. unsigned char *inbuf;        /* input buffer 1024 characters */
  57. unsigned int inptr;            /* 0..1023 offset to current character */ 
  58. unsigned long inbufsize;    /* working size of input buffer */
  59. int infilenum;                /* input refnum */
  60.  
  61. #define OUTBUFMAX 2046        /* ideal maximum size of output buffer */
  62. unsigned char *outbuf;        /* output buffer 2046 characters */
  63. unsigned int outptr;        /* 0..2045 offset to current character */ 
  64. unsigned long outbufsize;    /* working size of output buffer */
  65. int outfilenum;                /* output refnum */
  66.  
  67. int theID;                    /* Resource ID (output) */
  68.  
  69. /* hex (in string) to integer */
  70. int htoi(char *s)
  71. {
  72.     register int i, n;
  73.     register char h, hh;
  74.  
  75.     n = 0;
  76.     for (i=0;
  77.              (h = (s[i]>='0' && s[i]<='9'))
  78.              || (hh = (s[i] >= 'a' && s[i] <= 'h'))
  79.              || (s[i] >= 'A' && s[i] <= 'H');
  80.          ++i)
  81.         if (h)
  82.              n = 16 * n + (s[i] - '0');
  83.         else if (hh)
  84.             n = 16 * n + (s[i] - 'a' + 10);
  85.         else
  86.             n = 16 * n + (s[i] - 'A' + 10);
  87.     return n;
  88. }
  89.  
  90. /* Get input filename via Std File */
  91. /* returns refnum of opened file */
  92. int getinfile(Str255 filename)
  93. {
  94.     Point where;
  95.     SFReply reply;
  96.     int refnum;
  97.     OSErr err;
  98.     
  99.     where.v = 55;
  100.     where.h = 100;
  101.  
  102.     SFGetFile(where,"\pInput",nil,-1,nil,nil,&reply);
  103.     if (reply.good) {
  104.         err = FSOpen(reply.fName,reply.vRefNum,&refnum);
  105.         if (err == noErr) {
  106.             sprintf(filename,"%s.res",PtoCstr(reply.fName));
  107.             return refnum;        /* return refNum (assume nonzero) */
  108.         }
  109.         else {
  110.             printf("Error opening input file: #%d\n",err);
  111.             return 0;
  112.         }
  113.     }
  114.     else {
  115.         printf("Error getting file: #%d\n",err);
  116.         return 0;
  117.     }
  118. }
  119.  
  120. /* Open output file as resource file */
  121. /* return refnum of resource */
  122. int getoutfile(Str255 filename)
  123. {
  124.     Point where;
  125.     SFReply reply;
  126.     int refnum;
  127.     OSErr err;
  128.     OSType creator, type;
  129.     
  130.     where.v = 55;
  131.     where.h = 100;
  132.  
  133.     SFPutFile(where,"\pOutput",CtoPstr(filename),nil,&reply);
  134.     if (reply.good) {
  135.         creator = 'ASPF';
  136.         type = 'LWFN';
  137.         err = Create(reply.fName,reply.vRefNum,creator,type);
  138.         if ((err == dupFNErr)
  139.             && (FSDelete(reply.fName,reply.vRefNum) != noErr)) {
  140.                 printf("Error overwriting output file\n");
  141.                 return(0);
  142.             }
  143.         if (err == noErr) {
  144.             SetVol(nil,reply.vRefNum);
  145.             CreateResFile(reply.fName);
  146.             refnum = OpenResFile(reply.fName);
  147.             if (refnum == -1) {
  148.                 return(0);
  149.             }
  150.             else return (refnum);
  151.         }
  152.         else {
  153.             printf("Error creating output file: #%d\n",err);
  154.             return 0;
  155.         }
  156.     }
  157.     else {
  158.         printf("Error getting output file: #%d\n",err);
  159.         return 0;
  160.     }
  161. }
  162.  
  163. /* Allocate buffers */
  164. /* inbuf should be indexed 0..1023 */
  165. /* outbuf should be indexed 0..2045 */
  166. void initbuf()
  167. {
  168.     inbufsize = INBUFMAX;
  169.     inbuf = (unsigned char *) NewPtr(sizeof(unsigned char) * (inbufsize));
  170.     inptr = inbufsize;    /* force read from disk on first input() */
  171.     
  172.     outbufsize = OUTBUFMAX;
  173.     outbuf = (unsigned char *) NewPtr(sizeof(unsigned char) * (outbufsize));
  174.     outptr = 0;
  175.     
  176.     theID = 501;        /* first/lowest POST resource number */
  177.     return;
  178. }
  179.  
  180. /* input
  181.     get the next sequential input character from the input buffer
  182.     if the buffer is exhausted, refill it from disk
  183.    returned in argument ... eofErr or noErr will be function value
  184. */
  185. OSErr input(char *c)
  186. {
  187.     long count;                /* size (to be) read in from infile */
  188.     OSErr err = noErr;
  189.     
  190.     /* inptr is 0..1023 */
  191.     if (inptr == inbufsize) {    /* reached end of buffer */
  192.         if (inbufsize != INBUFMAX) {    /* which was not a full buffer */
  193.             return(eofErr);
  194.         }
  195.         else {
  196.             /* Read a clump of input data */
  197.             inbufsize = INBUFMAX;
  198.             err = FSRead(infilenum,&inbufsize,inbuf);    /* ? eofErr, noErr */
  199.             if ((err == eofErr) && (inbufsize > 0))
  200.                 err = noErr;    /* no real eofErr until buffer empty */
  201.             inptr = 0;
  202.             printf("Read %ld bytes\n",inbufsize);
  203.         }
  204.     }
  205.     *c = inbuf[inptr++];
  206.     return err;
  207. }
  208.  
  209. /* output - add a character to the output buffer
  210.    if buffer fills up, output a text resource
  211.    returned in argument ... eofErr or noErr will be function value */
  212. int output(char c, char resnum)
  213. {
  214.     long count;                /* size (to) read in from infile */
  215.     int err;
  216.     
  217.     /* outptr is 0..2045 - when it hits 2046, flush the buffer */
  218.     if (outptr == outbufsize) {
  219.         err = writeres(resnum);
  220.         outptr = 0;
  221.         outbuf[outptr++] = c;
  222.         return(err);
  223.     }
  224.     else {
  225.         outbuf[outptr++] = c;
  226.         return noErr;
  227.     }
  228. }
  229.  
  230. /* writeres (char resnum)
  231.     write the output buffer as a resource of type resnum
  232.     reset the output buffer
  233.     update the (next) output resource number 
  234. */
  235. int writeres(char resnum)
  236. {
  237.     ResType thetype;
  238.     char **newres;
  239.     char *masterptr;
  240.     int i;
  241.     
  242.     /* outptr is 2046 in full case (one past last written index) */
  243.     /* let new res be 2048 bytes long */
  244.     newres = NewHandle(outptr+2);    /* outptr already points 1 past end */
  245.     
  246.     HLock(newres);            /* get a pointer to the new block */
  247.     masterptr = *newres;
  248.     
  249.     masterptr[0] = resnum;    /* first byte in resource defines the type */
  250.     masterptr[1] = '\000';    /* always seems to be a null here */
  251.     for (i=0; i < outptr; i++) {
  252.         masterptr[i+2] = outbuf[i];
  253.     }
  254.     HUnlock(newres);        /* new block is created */
  255.     
  256.     thetype = 'POST';
  257.     AddResource(newres,thetype,theID,"\p");
  258.     if (ResError() == addResFailed)
  259.         return(addResFailed);
  260.     WriteResource(newres);
  261.     printf("Wrote resource %d\n",theID);
  262.     theID++;
  263.     return;
  264. }
  265.  
  266. /* cvt text font file into resource font file
  267.  
  268. algorithm:
  269. initialize buffers
  270. read ascii data until 'eexec', copying into POST resources of type 1
  271. read eexec data until 512 zeros, converting to binary and
  272.     copying into POST resources of type 2
  273. read ascii data until eof (starting with the first zero), copying
  274.     into a POST resource type 1
  275. output a POST resource type 5 (End of font program)
  276. */
  277. void cvt()
  278. {
  279.     ResType thetype;        /* resource type */
  280.     int theID;                /* resource ID */
  281.     char c,d;
  282.     int match;                /* number of characters that match pattern */
  283.     char outtwo[3] = "\000\000\000";    /* third byte is an end for htoi */
  284.     int i,notfirsttime;
  285.     char outc;
  286.     OSErr err;
  287.     
  288.     initbuf();
  289.     match = 0;
  290.     
  291.     while ((match < 6) && (input(&c) != eofErr)) {
  292.         if (((match == 0) && (c == 'e')) 
  293.             || ((match == 1) && (c == 'e'))
  294.             || ((match == 2) && (c == 'x'))
  295.             || ((match == 3) && (c == 'e'))
  296.             || ((match == 4) && (c == 'c'))
  297.             || ((match == 5) && ((c == '\r') || (c == '\n')))) {
  298.                 match++;
  299.                 /*printf("+");*/    /* for debug */
  300.         }
  301.         else {
  302.             match = 0;    /* not a complete match */
  303.         }
  304.         output(c,ASCIIDATA);
  305.         /*if (c == '\r') printf("\n");    /* for debugging *
  306.         else
  307.             printf("%c",c);*/
  308.     }
  309.     printf("eexec found\n");
  310.     writeres(ASCIIDATA);    /* flush type 1 resource */
  311.     outptr=0;
  312.     
  313.     printf("----ascii parts finished-----");
  314.     
  315.     /* ASCII parts written, now write binary data until 512 zeros */
  316.     /* reset input file to the start of binary data */
  317.     err = SetFPos(infilenum,fsFromMark,(long) ( - (inbufsize - inptr)));
  318.     /* reset input buffer - want to read in from file again */
  319.     inptr = inbufsize;
  320.     
  321.     i=0;
  322.     match = 0;    /* number of 00s in a row */
  323.     
  324.     /* "512 zeros" is really 256 zeros in binary */
  325.     while ((match < 256) && (input(&c) != eofErr)) {
  326.         /*printf("%c",c);*/
  327.         if (isspace(c))            /* skip over whitespace */
  328.             continue;
  329.         else if ((c == '0') && (i == 0)) {        /* input is 0. */
  330.             input(&d);
  331.             if (d == '0') {
  332.                 match++;
  333.             }
  334.             else {
  335.                 if (match > 0) {    /* we had 00s before */
  336.                     for (; match > 0; --match) output('\000',HEXDATA);
  337.                 }
  338.                 outtwo[0]='0';
  339.                 outtwo[1]=d;
  340.                 outc = htoi(outtwo);
  341.                 output(outc,HEXDATA);
  342.             }
  343.         }
  344.         else {
  345.             if (match > 0) {    /* input not zero, but we had 00 before */
  346.                 for (; match > 0; --match) output('\000',HEXDATA);
  347.             }
  348.             if (i == 0)
  349.                 outtwo[i++] = c;            /* 'c.' i=1 */
  350.             else {
  351.                 outtwo[i--] = c;            /* 'cc' i=0 */
  352.                 outc = htoi(outtwo);
  353.                 output(outc,HEXDATA);
  354.             }
  355.         }
  356.     } /* while */
  357.  
  358.     /* 512 zeros found (or eof) */
  359.     writeres(HEXDATA);
  360.     printf("-----Hex data finished-----\n");
  361.     outptr=0;
  362.     
  363.     for (match=0;match < 8;++match) {
  364.         for (i=0; i < 64; ++i) output('0',ASCIIDATA);
  365.         output('\r',ASCIIDATA);
  366.     }
  367.     sprintf(inbuf,"cleartomark\n");
  368.  
  369.     for (i=0; i < 12; ++i)
  370.         output(inbuf[i],ASCIIDATA);
  371.     
  372.     writeres(ASCIIDATA);
  373.     printf("-----Ascii 0000 data finished-----\n");
  374.     
  375.     outptr=0;
  376.     writeres(ENDOFFONT);
  377. }
  378.  
  379. void resumeProc ()
  380. {
  381. }
  382.  
  383. void main(int argc, char *argv[])
  384. {
  385.     Str255 filename;
  386.     
  387.     /* Standard Initialization Stuff */
  388.     InitGraf(&thePort);
  389.     InitFonts();
  390.     FlushEvents(everyEvent,0);
  391.     InitWindows();
  392.     InitMenus();
  393.     TEInit();
  394.     InitDialogs(&resumeProc);
  395.     InitCursor();
  396.  
  397.     for (;;) {
  398.     printf("reAdobe 1.1: Type 1 Font text -> resource format converter\n");
  399.     printf("Copyright 1991 by Rob Elliott. All rights reserved.\n");
  400.     printf("May be freely distributed.  Pardon the lousy interface ...\n\n");
  401.     printf("Select a font in text format to be converted (cancel to quit):\n");
  402.  
  403.     infilenum = getinfile(filename);
  404.     if (infilenum) {
  405.         printf("Select a filename for the font in resource format:\n");
  406.         outfilenum = getoutfile(filename);
  407.         
  408.         if (outfilenum) {
  409.             printf("Converting ...\n");
  410.             cvt();
  411.             CloseResFile(outfilenum);
  412.         }
  413.         else
  414.             return;
  415.         FSClose(infilenum);
  416.     }
  417.     else
  418.         return;
  419.     }
  420. }
  421.